from ctypes import *
import win32api
import psutil
import win32gui
import win32process
import re

FAGE_READWRITE = 0x04
PROCESS_ALL_ACCESS = 0x001F0FFF
VIRTUAL_MEN = (0x1000 | 0x2000)

kernel32 = windll.kernel32
user32 = windll.user32

# 获取所有窗口句柄+窗口标题 存入字典中
def get_all_ths_windows():
    ths_windows = []

    def enum_windows_proc(hwnd, lParam):
        windows = lParam
        tdx_temp = dict()
        if (re.match("通达信", win32gui.GetWindowText(hwnd))) and (
                win32gui.GetClassName(hwnd) == 'TdxW_MainFrame_Class'):
            hread_id, p_id = win32process.GetWindowThreadProcessId(
                hwnd)  # 通过句柄获取【线程ID 进程ID】
            tdx_temp.update({"pid": p_id, "hwnd": hwnd, "title": win32gui.GetWindowText(
                hwnd), "clsname": win32gui.GetClassName(hwnd)})
            windows.append(tdx_temp)
        if (re.match("同花顺", win32gui.GetWindowText(hwnd))) and (re.match("Afx:00", win32gui.GetClassName(hwnd))):
            hread_id, p_id = win32process.GetWindowThreadProcessId(
                hwnd)  # 通过句柄获取【线程ID 进程ID】
            tdx_temp.update({"pid": p_id, "hwnd": hwnd, "title": win32gui.GetWindowText(
                hwnd), "clsname": win32gui.GetClassName(hwnd)})
            windows.append(tdx_temp)

    win32gui.EnumWindows(enum_windows_proc, ths_windows)
    return ths_windows


# 取一个同花顺顶层窗口句柄
def ths_top_hwnd():
    process_lists = get_all_ths_windows()  # 返回进程字典
    # keys = dict_ths.keys()  # 返回字典中所有键
    # items = dict_tdx.items()  # 返回键值对
    for process in process_lists:
        pid = process["pid"]  # 当前进程id
        hwnd = process["hwnd"]  # 当前进程句柄
        # print(
        #     f"当前进程id:{pid} 当前句柄：{hwnd}===窗口标题：{win32gui.GetWindowText(hwnd)}===类名：{win32gui.GetClassName(hwnd)}")
        if re.match("同花顺", win32gui.GetWindowText(hwnd)):
            return hwnd
    return 0


def ths_prc_hwnd():
    pl = psutil.pids()
    for pid in pl:
        if psutil.Process(pid).name().lower() == "hexin.exe":
            if isinstance(pid, int):
                ths_process_hwnd = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False,
                                                        int(pid))  # 申请内存所在的进程句柄
                return ths_process_hwnd

def bytes_16(dec_num, Code):
    ascii_char = chr(dec_num)  # 将整数转换为对应的ASCII字符
    codex = ascii_char + str(Code)
    # 将Python字符串转换为bytes类型
    bytes_codex = codex.encode('ascii', 'ignore')
    return bytes_codex


def ths_convert_code(Code):
    # 上海，深圳股票判断;
    if str(Code)[0] == '6':
        dec_num = int("11", 16)  # 将16进制数转换为整数
        bytes_codex = bytes_16(dec_num,Code)
    elif str(Code).startswith("11"):  # 11开头的可转债
        dec_num = int("13", 16)  # 将16进制数转换为整数
        bytes_codex = bytes_16(dec_num,Code)
    elif str(Code).startswith("12"):  # 12开头的可转债
        dec_num = int("23", 16)  # 将16进制数转换为整数
        bytes_codex = bytes_16(dec_num,Code)
    else:
        dec_num = int("21", 16)  # 将16进制数转换为整数
        bytes_codex = bytes_16(dec_num,Code)
    return bytes_codex

def send_code_message(code):
    ths_process_hwnd = ths_prc_hwnd()
    # 用kerne132.VirtualAllocEx在目标进程开辟内存空间(用于存放数据)
    argv_address = kernel32.VirtualAllocEx(ths_process_hwnd, 0, 8, VIRTUAL_MEN, FAGE_READWRITE)
    bytes_str = ths_convert_code(code)
    # 步用kerne132.WriteProcessMemory在目标进程内存空间写入数据
    kernel32.WriteProcessMemory(ths_process_hwnd, argv_address, bytes_str, 7, None)
    ths_top_hwnd1 = ths_top_hwnd()  # 同花顺顶层窗口句柄
    win32api.SendMessage(ths_top_hwnd1, int(1168), 0, argv_address)

if __name__ == '__main__':
    # 让同花顺切换到688168
    send_code_message("002272")
    # accessibleName = 'tableWidget_bk_sub_5'
    # suffix = accessibleName[accessibleName.rfind('_') + 1:]
    # print(suffix)



